#include "../include/Debug.h"
#include "../include/Reactor.h"
#include "../include/Acceptor.h"
#include "../include/InetAddr.h"
#include "../include/SvcHandler.h"
#include "../include/TaskWithMQ.h"
#include "../include/EpollReactor.h"
#include "../include/ThreadManager.h"

#include <assert.h>

THREAD_FUNC_RETURN_T event_loop (void *arg)
{
    Reactor *r = reinterpret_cast<Reactor*> (arg);
    r->run_reactor_event_loop ();
    NDK_DBG ("reactor event loop done");
    return 0;
}
// --------------------------------------------------------
enum
{
    TRANSFER_FILE  = 200,
    ECHO_MSG	   = 202,
    EXIT_CMD	   = 204
};
struct MsgHeader
{
    int msgid;
    int msglen;  // not include header
};
#define MAX_BUFF_LEN           1440

class MsgHandleTask : public TaskWithMQ
{
public:
    MsgHandleTask ()
    : TaskWithMQ (ThreadManager::instance ())
    {
    }
    
    ~MsgHandleTask (){}
    virtual int open (void * = 0)
    {
	return 0;//this->activate ();
    }
    virtual int svc ()
    {
	MessageBlock *mb = 0;
	while (1)
	{
	    this->getq (mb);
	    NDK_INF ("msgqueue get a mb\n");
	}
	return 0;
    }
};
MsgHandleTask msg_handle_task;
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Server : public SvcHandler
{
public:
    Server () 
    {
	NDK_INF ("server constructor %d\n", count_++);
	buff_  = new char[MAX_BUFF_LEN];
    }
    ~Server (){ NDK_INF ("server destructor\n");}
    virtual int open (void *arg)
    {
	NDK_INF ("server open\n");
	unused_arg (arg);
	assert (SvcHandler::open (0) == 0);
    }
    virtual int handle_input (NDK_HANDLE handle)
    {
	unused_arg (handle);
	MsgHeader msgh;
	int result = 0;
	if ((result = this->peer ().recv_n (&msgh, sizeof (msgh))) < 0)
	{
	    NDK_DBG ("recv_n msg header error");
	    return -1;
	}
	if (result == 0)
	{
	    NDK_INF ("peer close when recv header\n");
	    return -1;
	}
	memset (this->buff_, 0, MAX_BUFF_LEN);
	if ((result = this->peer ().recv_n (this->buff_, MAX_BUFF_LEN)) <= 0)
	{
	    NDK_DBG ("recv_n msg body error");
	    return -1;
	}	    
	if (result == 0)
	{
	    NDK_INF ("peer close when recv msg body\n");
	    return -1;
	}
	//NDK_INF ("recv a msg\n");
	return 0;
    }
protected:
    char *buff_;
    static int count_;
};
int Server::count_ = 0;
int main (int argc, char *argv[])
{
    int port = atoi (argv[1]);
    port = 8889;
    EpollReactor *er = new EpollReactor;
    Reactor *r = new Reactor (er);
    Reactor::instance (r);
    msg_handle_task.open ();
    Acceptor<Server> acceptor (Reactor::instance ());
    ThreadManager::instance ()->spawn_n (1, event_loop, Reactor::instance ());
    InetAddr local_addr (port);
    acceptor.open (local_addr,
	    Reactor::instance (),
	    1,
	    1024 * 1024 * 2);
    ThreadManager::instance ()->wait ();
    return 0;
}



